/**
 * 请求队列管理器 - 用于在离线时存储API请求并在网络恢复时发送
 */

/**
 * 请求队列类
 */
class RequestQueue {
  constructor() {
    this.queueName = 'apiRequestQueue';
    this.dbName = 'pwaAppDB';
    this.dbVersion = 1;
    this.db = null;
  }

  /**
   * 初始化IndexedDB
   */
  async initDB() {
    if (this.db) {
      return this.db;
    }

    return new Promise((resolve, reject) => {
      if (!('indexedDB' in window)) {
        reject(new Error('浏览器不支持IndexedDB'));
        return;
      }

      const request = indexedDB.open(this.dbName, this.dbVersion);

      request.onupgradeneeded = (event) => {
        const db = event.target.result;
        
        // 创建对象存储空间来存储请求
        if (!db.objectStoreNames.contains(this.queueName)) {
          const store = db.createObjectStore(this.queueName, {
            keyPath: 'id',
            autoIncrement: true
          });
          
          // 创建索引以提高查询性能
          store.createIndex('status', 'status', { unique: false });
          store.createIndex('timestamp', 'timestamp', { unique: false });
        }
      };

      request.onsuccess = (event) => {
        this.db = event.target.result;
        resolve(this.db);
      };

      request.onerror = (event) => {
        reject(event.target.error);
      };
    });
  }

  /**
   * 将请求添加到队列
   * @param {string} url - 请求URL
   * @param {Object} options - 请求选项
   * @returns {Promise<string>} 请求ID
   */
  async addToQueue(url, options = {}) {
    try {
      const db = await this.initDB();
      
      const requestData = {
        url,
        options: {
          ...options,
          headers: { ...options.headers },
          // 确保请求体是可序列化的
          body: options.body ? JSON.stringify(options.body) : null
        },
        status: 'pending',
        timestamp: new Date().toISOString()
      };

      return new Promise((resolve, reject) => {
        const transaction = db.transaction([this.queueName], 'readwrite');
        const store = transaction.objectStore(this.queueName);
        const addRequest = store.add(requestData);

        addRequest.onsuccess = (event) => {
          const requestId = event.target.result;
          console.log(`请求已添加到队列: ID=${requestId}`);
          resolve(requestId.toString());
        };

        addRequest.onerror = (event) => {
          console.error('添加请求到队列失败:', event.target.error);
          reject(event.target.error);
        };
      });
    } catch (error) {
      console.error('添加请求到队列时出错:', error);
      throw error;
    }
  }

  /**
   * 获取队列中的所有请求
   * @returns {Promise<Array>} 请求列表
   */
  async getQueue() {
    try {
      const db = await this.initDB();

      return new Promise((resolve, reject) => {
        const transaction = db.transaction([this.queueName], 'readonly');
        const store = transaction.objectStore(this.queueName);
        const getAllRequest = store.getAll();

        getAllRequest.onsuccess = (event) => {
          resolve(event.target.result);
        };

        getAllRequest.onerror = (event) => {
          console.error('获取请求队列失败:', event.target.error);
          reject(event.target.error);
        };
      });
    } catch (error) {
      console.error('获取请求队列时出错:', error);
      throw error;
    }
  }

  /**
   * 从队列中移除请求
   * @param {string} requestId - 请求ID
   * @returns {Promise<void>}
   */
  async removeFromQueue(requestId) {
    try {
      const db = await this.initDB();

      return new Promise((resolve, reject) => {
        const transaction = db.transaction([this.queueName], 'readwrite');
        const store = transaction.objectStore(this.queueName);
        const deleteRequest = store.delete(Number(requestId));

        deleteRequest.onsuccess = () => {
          console.log(`请求已从队列中移除: ID=${requestId}`);
          resolve();
        };

        deleteRequest.onerror = (event) => {
          console.error('从队列中移除请求失败:', event.target.error);
          reject(event.target.error);
        };
      });
    } catch (error) {
      console.error('从队列中移除请求时出错:', error);
      throw error;
    }
  }

  /**
   * 更新请求状态
   * @param {string} requestId - 请求ID
   * @param {string} status - 新状态
   * @param {Object} data - 附加数据（如响应结果或错误信息）
   * @returns {Promise<void>}
   */
  async updateRequestStatus(requestId, status, data = null) {
    try {
      const db = await this.initDB();

      return new Promise((resolve, reject) => {
        const transaction = db.transaction([this.queueName], 'readwrite');
        const store = transaction.objectStore(this.queueName);
        const getRequest = store.get(Number(requestId));

        getRequest.onsuccess = (event) => {
          const requestData = event.target.result;
          if (requestData) {
            requestData.status = status;
            requestData.updatedAt = new Date().toISOString();
            
            if (data) {
              requestData.result = data;
            }

            const updateRequest = store.put(requestData);
            
            updateRequest.onsuccess = () => {
              console.log(`请求状态已更新: ID=${requestId}, 状态=${status}`);
              resolve();
            };
            
            updateRequest.onerror = (e) => {
              console.error('更新请求状态失败:', e.target.error);
              reject(e.target.error);
            };
          } else {
            reject(new Error(`未找到ID为 ${requestId} 的请求`));
          }
        };

        getRequest.onerror = (event) => {
          console.error('获取请求数据失败:', event.target.error);
          reject(event.target.error);
        };
      });
    } catch (error) {
      console.error('更新请求状态时出错:', error);
      throw error;
    }
  }

  /**
   * 清除队列中的所有请求
   * @returns {Promise<void>}
   */
  async clearQueue() {
    try {
      const db = await this.initDB();

      return new Promise((resolve, reject) => {
        const transaction = db.transaction([this.queueName], 'readwrite');
        const store = transaction.objectStore(this.queueName);
        const clearRequest = store.clear();

        clearRequest.onsuccess = () => {
          console.log('请求队列已清空');
          resolve();
        };

        clearRequest.onerror = (event) => {
          console.error('清空请求队列失败:', event.target.error);
          reject(event.target.error);
        };
      });
    } catch (error) {
      console.error('清空请求队列时出错:', error);
      throw error;
    }
  }
}

// 创建单例实例
const requestQueue = new RequestQueue();

export default requestQueue;

export {
  RequestQueue
};